#include <isa.h>
#include <cpu/cpu.h>
#include <difftest-def.h>
#include <memory/paddr.h>
word_t isa_raise_intr(word_t NO, vaddr_t epc);

struct  diff_CPU_state{
	word_t gpr[32];
	word_t pc;
};

void difftest_memcpy(paddr_t addr, void *buf, size_t n, bool direction) {
 	if (direction == DIFFTEST_TO_REF){
		paddr_t waddr = addr;
	  for(size_t i = 0; i< n; i++){
		  paddr_write(waddr++,1,*((uint8_t *)buf+i));
//	  	  printf("in addr:%x,memcpy:%x\n",waddr,*((uint8_t *)buf+i));
	  }
	}
	else{
		assert(0);
	}
}

void difftest_regcpy(void *dut, bool direction) {
  if(direction == DIFFTEST_TO_REF){
    struct diff_CPU_state* ctx = (struct diff_CPU_state *)dut;
    for (int i = 0; i < 32;i++){
  	cpu.gpr[i] = ctx->gpr[i];
    }
    	cpu.pc = ctx->pc;
//	printf("ctx->pc:%lx,to ref\n",ctx->pc);
  }else{
    if(direction == DIFFTEST_TO_DUT){
      struct diff_CPU_state* ctx = (struct diff_CPU_state *)dut;
      for (int i = 0; i < 32;i++){
  	ctx->gpr[i] = cpu.gpr[i];
//	printf("ctx:%lx,cpu:%lx\n",ctx->gpr[i],cpu.gpr[i]);
      }
    	ctx->pc = cpu.pc;
    }
  }
}

void difftest_exec(uint64_t n) {
  	cpu_exec(n);
	//assert(0);
}

void difftest_raise_intr(word_t NO) {
//  assert(0);
    isa_raise_intr(NO,cpu.pc);
}

void difftest_init() {
  /* Perform ISA dependent initialization. */
  init_isa();
}
